﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gurucore.Framework.DataAccess.Persistence.QueryLanguage
{
	public abstract class Operand
	{
		public abstract string ToExpressionString(IExpressionMaker p_expressionMaker);

		public static implicit operator Operand(string p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public static implicit operator Operand(int p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public static implicit operator Operand(double p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public static implicit operator Operand(decimal p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public static implicit operator Operand(Guid p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public static implicit operator Operand(DateTime p_obj)
		{
			return new ConstantOperand(p_obj);
		}

		public Expression And(Operand p_secondOperand)
		{
			return new Expression(this, Operator.And, p_secondOperand);
		}

		public static Expression operator &(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.And(p_secondOperand);
		}

		public Expression Or(Operand p_oSecondOperand)
		{
			return new Expression(this, Operator.Or, p_oSecondOperand);
		}

		public static Expression operator |(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Or(p_secondOperand);
		}

		public Expression Xor(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Xor, p_secondOperand);
		}

		public Expression Not()
		{
			return new Expression(Operator.Not, this);
		}

		public static Expression operator !(Operand p_operand)
		{
			return p_operand.Not();
		}

		public Expression Add(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Add, p_secondOperand);
		}

		public static Expression operator +(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Add(p_secondOperand);
		}

		public Expression Sub(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Sub, p_secondOperand);
		}
		
		public static Expression operator -(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Sub(p_secondOperand);
		}

		public Expression Mul(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Mul, p_secondOperand);
		}

		public static Expression operator *(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Mul(p_secondOperand);
		}

		public Expression Div(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Div, p_secondOperand);
		}

		public static Expression operator /(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Div(p_secondOperand);
		}

		public Expression Like(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Like, p_secondOperand);
		}

		public Expression In(SetOperand p_secondOperand)
		{
			return new Expression(this, Operator.In, p_secondOperand);
		}

		public Expression NotIn(SetOperand p_secondOperand)
		{
			return new Expression(this, Operator.NotIn, p_secondOperand);
		}

		public Expression Between(RangeOperand p_secondOperand)
		{
			return new Expression(this, Operator.Between, p_secondOperand);
		}

		public Expression Gt(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Gt, p_secondOperand);
		}

		public static Expression operator >(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Gt(p_secondOperand);
		}

		public Expression Lt(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Lt, p_secondOperand);
		}

		public static Expression operator <(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Lt(p_secondOperand);
		}

		public Expression Eq(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Eq, p_secondOperand);
		}

		public static Expression operator ==(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Eq(p_secondOperand);
		}

		public Expression Neq(Operand p_secondOperand)
		{
			return new Expression(this, Operator.Neq, p_secondOperand);
		}

		public static Expression operator !=(Operand p_firstOperand, Operand p_secondOperand)
		{
			return p_firstOperand.Neq(p_secondOperand);
		}

		public Expression Gte(Operand p_oSecondOperand)
		{
			return new Expression(this, Operator.Gte, p_oSecondOperand);
		}

		public Expression Lte(Operand p_oSecondOperand)
		{
			return new Expression(this, Operator.Lte, p_oSecondOperand);
		}

		public Expression IsNull()
		{
			return new Expression(this, Operator.IsNull);
		}

		public Expression IsNotNull()
		{
			return new Expression(this, Operator.IsNotNull);
		}

		public Alias As(string p_sAlias)
		{
			return new Alias(this, p_sAlias);
		}

		public Aggregation Count()
		{
			return Aggregation.COUNT;
		}

		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
	}
}
